//
// Created by myrica on 2/17/25.
//

#ifndef ASTSTATEMENT_H
#define ASTSTATEMENT_H

#include <vector>
#include <utility>
#include <map>
#include <optional>

#include "ASTBase.h"

namespace ast {
    using std::vector;
    using std::map;
    using std::optional;
    using std::unique_ptr;

    using namespace ast;

    struct StatementCompound final : Statement {
        vector<ASTBase *> children;

        explicit StatementCompound(const vector<ASTBase *> &children) : Statement(Compound), children(children) {
        }

        static bool classof(const ASTBase *stmt) {
            return stmt->getKind() == Compound;
        }
    };

    struct StatementExpression final : Statement {
        ast::Expression *expression;

        explicit StatementExpression(ast::Expression *expression) : Statement(ExpressionStatement),
                                                                    expression(expression) {
        }

        static bool classof(const ASTBase *stmt) {
            return stmt->getKind() == ExpressionStatement;
        }
    };

    struct StatementReturn final : Statement {
        ast::Expression *return_value;

        explicit StatementReturn(ast::Expression *return_value) : Statement(Return),
                                                                  return_value(return_value) {
        }

        static bool classof(const ASTBase *stmt) {
            return stmt->getKind() == Return;
        }
    };

    struct StatementIfElse final : Statement {
        ast::Expression *condition;
        Statement *then_content;
        Statement *else_content;

        StatementIfElse(ast::Expression *condition,
                        Statement *if_content,
                        Statement *else_content) : Statement(IfElse), condition(condition),
                                                   then_content(if_content),
                                                   else_content(else_content) {
        }

        static bool classof(const ASTBase *stmt) {
            return stmt->getKind() == IfElse;
        }
    };

    struct StatementWhile final : Statement {
        ast::Expression *condition;
        Statement *while_content;

        StatementWhile(ast::Expression *cond, Statement *while_content) : Statement(While), condition(cond),
                                                                          while_content(while_content) {
        }

        static bool classof(const ASTBase *stmt) {
            return stmt->getKind() == While;
        }
    };

    struct StatementBreak final : Statement {
        explicit StatementBreak() : Statement(Break) {
        }

        static bool classof(const ASTBase *stmt) {
            return stmt->getKind() == Break;
        }
    };
    struct StatementContinue final : Statement {
        explicit StatementContinue() : Statement(Continue) {
        }

        static bool classof(const ASTBase *stmt) {
            return stmt->getKind() == Continue;
        }
    };

    // todo: 其他statement
}

#endif //ASTSTATEMENT_H
